library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity mod_Unit is
	generic(
		Z : positive range 1 to 256 ;
		N : positive 
	);
	port(
		clk	: in std_logic ;
		reset	: in std_logic ;
		s_in	: in std_logic_vector(Z-1 downto 0 ) ;
		
		s_out	: out std_logic_vector(Z-1 downto 0 ) ;
		b_fin	: out std_logic 
	);
end entity ;

--------------------------------------------------------------------------------------------------------------------

architecture mod_Unit1 of mod_Unit is

signal s_modulo_in : unsigned(Z-1 downto 0) ;
signal s_modulo_out : unsigned(Z-1 downto 0) ;

signal s_modulo_orig_in : unsigned(Z-1 downto 0)  ;
signal s_modulo_orig_out : unsigned(Z-1 downto 0);

signal etat_modulo_in : std_logic_vector(1 downto 0) ;
signal etat_modulo_out : std_logic_vector(1 downto 0) ;

begin
	
	-- Partie dédiee au calcul de modulo
	
	MEM : process( clk, reset )
	begin
		if reset = '1' then
			etat_modulo_out <= "00";
			s_modulo_out <= (others => '0') ;
			s_modulo_orig_out <= (others => '0') ;
		end if ;

		if( clk'event AND clk = '1') then 
				etat_modulo_out <= etat_modulo_in ;
				s_modulo_out <= s_modulo_in ;
				s_modulo_orig_out <= s_modulo_orig_in ;
		end if ;
		
	end process ;
	
	
	COMB : process( etat_modulo_out, s_modulo_out, s_modulo_orig_out, s_in )
	begin
		s_modulo_orig_in <= s_modulo_orig_out ;
		etat_modulo_in <= "00";
		b_fin <= '0' ;
		s_out <= (others => '0') ;
		
		if( unsigned(s_in) /= s_modulo_orig_out ) then
			etat_modulo_in <= "01" ;
			s_modulo_in <=unsigned(s_in) ;
			s_modulo_orig_in <= unsigned(s_in) ;
			
		elsif( etat_modulo_out = "00" ) then
			s_modulo_in <= s_modulo_out ;
			s_out <= std_logic_vector(s_modulo_out) ;
			etat_modulo_in <= "10" ;
			b_fin <= '0' ;
			
		elsif( etat_modulo_out = "01" ) then
			
			if( s_modulo_out >= N ) then
				s_modulo_in <= ( s_modulo_out - N ) ;
				etat_modulo_in <= etat_modulo_out ;
			else
				s_modulo_in <= s_modulo_out ;
				etat_modulo_in <= "10" ;
			end if ;
                        
                elsif( etat_modulo_out = "10" ) then
		       	s_modulo_in <= s_modulo_out ;
			s_out <= std_logic_vector(s_modulo_out) ;
			etat_modulo_in <= "10" ;
			b_fin <= '1' ;
     
		else
			etat_modulo_in <= "00" ;
			s_modulo_in <= s_modulo_out ;
		end if ;
		
	end process ;
end architecture;
	-- Fin de la partie dédiee au calcul de modulo
